﻿using System.Collections;
using System.Text;
using Basic.FormCollect;
using Basic.FormExtendService;
using Basic.FormModel.Column;
using Basic.FormModel.UserRecord;
using Basic.FormRemoteModel;
using Basic.FormRemoteModel.UserRecord.Model;
using Basic.UserFormService.Interface;
using LinqKit;
using WeDonekRpc.CacheClient.Interface;
using WeDonekRpc.Helper;
using WeDonekRpc.Helper.Validate;

namespace Basic.UserFormService.lmpl
{
    internal class UserRecordService : IUserRecordService
    {
        private readonly IUserFormRecordCollect _Record;
        private readonly ITableColumnCollect _Column;
        private readonly IFileService _File;
        private readonly ICacheController _Cache;
        public UserRecordService ( IUserFormRecordCollect record,
            IFileService file,
            ICacheController cache,
            ITableColumnCollect column )
        {
            this._Cache = cache;
            this._File = file;
            this._Record = record;
            this._Column = column;
        }

        public bool CheckIsNull ( long formId, string linkType, long linkPK )
        {
            return this._Record.CheckIsNull(formId, linkType, linkPK);
        }
        private TableColDto[] _GetCols ( long formId )
        {
            string key = string.Concat("FormCol_", formId);
            if ( this._Cache.TryGet(key, out TableColDto[] cols) )
            {
                return cols;
            }
            cols = this._Column.GetsByFormId<TableColDto>(formId);
            _ = this._Cache.Set(key, cols, new TimeSpan(1, 0, 0, 0));
            return cols;
        }
        public UserRecordDto SetRecord ( RecordSet obj )
        {
            UserRecordAdd add = new UserRecordAdd
            {
                EmpId = obj.EmpId,
                FormId = obj.FormId,
                LinkPK = obj.LinkPK,
                LinkType = obj.LinkType
            };
            List<long> fileId = new List<long>();
            if ( !obj.Table.IsNull() )
            {
                TableColDto[] cols = this._GetCols(obj.FormId);
                List<UserRecordItem> items = new List<UserRecordItem>();
                obj.Table.ForEach(a =>
                {
                    if ( a.Rows.IsNull() )
                    {
                        return;
                    }
                    TableColDto[] col = cols.FindAll(c => c.TableId == a.TableId);
                    a.Rows.ForEach(e =>
                    {
                        col.ForEach(c =>
                        {
                            UserRecordItem item = new UserRecordItem
                            {
                                RowIndex = e.RowId,
                                TableId = a.TableId,
                                ColName = c.ColName,
                                ColumnId = c.Id,
                                IsNull = false,
                                ColType = c.ColType,
                                ItemType = FormRecordDataType.String
                            };
                            if ( e.Column.TryGetValue(c.ColName, out object val) )
                            {
                                if ( val == null || ( ( val is string i ) && i == string.Empty ) )
                                {
                                    item.IsNull = true;
                                }
                                else
                                {
                                    if ( c.DataType.HasValue )
                                    {
                                        item.ItemType = c.DataType.Value;
                                    }
                                    else if ( val is IList )
                                    {
                                        item.ItemType = FormRecordDataType.Array;
                                    }
                                    else
                                    {
                                        item.ItemType = FormRecordDataType.String;
                                    }
                                    if ( item.ItemType == FormRecordDataType.Long )
                                    {
                                        item.LongVal = Convert.ToInt64(val);
                                    }
                                    else if ( item.ItemType == FormRecordDataType.Date )
                                    {
                                        DateTime time = DateTime.Parse(Convert.ToString(val));
                                        item.LongVal = time.Date.ToLong();
                                    }
                                    else if ( item.ItemType == FormRecordDataType.DateTime )
                                    {
                                        DateTime time = DateTime.Parse(Convert.ToString(val));
                                        item.LongVal = time.ToLong();
                                    }
                                    else if ( item.ItemType == FormRecordDataType.Time )
                                    {
                                        string str = Convert.ToString(val);
                                        if ( str.Validate(ValidateFormat.小时分) )
                                        {
                                            string[] t = str.Split(':');
                                            item.LongVal = ( int.Parse(t[0]) * 60 ) + int.Parse(t[1]);
                                        }
                                        else
                                        {
                                            DateTime time = DateTime.Parse(str);
                                            item.LongVal = ( time.Hour * 60 ) + time.Minute;
                                        }
                                    }
                                    else if ( item.ItemType == FormRecordDataType.Bool )
                                    {
                                        item.BoolVal = Convert.ToBoolean(val);
                                    }
                                    else if ( item.ItemType == FormRecordDataType.Number )
                                    {
                                        item.NumVal = Convert.ToDecimal(val);
                                    }
                                    else if ( item.ItemType == FormRecordDataType.Array )
                                    {
                                        if ( val is IList arr )
                                        {
                                            if ( arr.Count > 0 )
                                            {
                                                if ( c.ColType == ControlType.Upload )
                                                {
                                                    StringBuilder str = new StringBuilder("|");
                                                    foreach ( string id in arr )
                                                    {
                                                        fileId.Add(long.Parse(id));
                                                        _ = str.Append(id);
                                                        _ = str.Append('|');
                                                    }
                                                    item.StrVal = str.ToString();
                                                }
                                                else
                                                {
                                                    StringBuilder str = new StringBuilder("|");
                                                    foreach ( string id in arr )
                                                    {
                                                        _ = str.Append(id);
                                                        _ = str.Append('|');
                                                    }
                                                    item.StrVal = str.ToString();
                                                }
                                            }
                                            else
                                            {
                                                item.IsNull = true;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        item.StrVal = val.ToString();
                                    }
                                }
                            }
                            else
                            {
                                item.IsNull = true;
                            }
                            items.Add(item);
                        });
                    });
                });
                add.Items = items.ToArray();
            }
            UserRecordDto record = this._Record.Sync(add);
            if ( fileId.Count > 0 )
            {
                this._File.Save(fileId.ToArray(), obj.LinkPK);
            }
            return record;
        }

    }
}
